package com.tian.arch.util

import android.content.Context
import android.content.res.ColorStateList
import android.graphics.drawable.ColorDrawable
import android.graphics.drawable.Drawable
import android.graphics.drawable.GradientDrawable
import android.graphics.drawable.StateListDrawable
import com.tian.arch.R


/**
 * 描述selector 状态的枚举
 */
enum class SelectorState(val state: Int) {
    Pressed(android.R.attr.state_pressed),
    Checked(android.R.attr.state_checked),
    Enabled(android.R.attr.state_enabled),
    Selected(android.R.attr.state_selected),
    Focused(android.R.attr.state_focused),
    WindowFocused(android.R.attr.state_window_focused)
}

/**
 * Shape线条宽度, 限制胡乱定义边框宽度
 */
enum class ShapeStokeWidth(val width: Int) {
    Px1(1),
    Px2(2),
    Px3(3),
    Dp2(2.dp().toInt()),
}

/**
 * Shape圆角定义,限制胡乱定义圆角弧度
 */
enum class ShapeCornerRadius(val radius: Float) {
    Radius1(1.dp()),
    Radius2(2.dp()),
    Radius4(4.dp()),
    Radius6(6.dp()),
    Radius8(8.dp()),
    Radius10(10.dp()),
    Radius12(12.dp()),
    Radius15(15.dp()),
    Radius16(16.dp()),
    Radius17(18.dp()),
    Radius20(20.dp()),
    Radius24(24.dp()),
    Radius96(96.dp()),
    RadiusNone(0f)
}


/**
 * 使用icon创建 单一状态selector
 */
fun createSelectorWithIcon(context: Context, normalId: Int, otherStateId: Int, selectorState: SelectorState): StateListDrawable {
    return createSelector(normalId.toResDrawable(context), otherStateId.toResDrawable(context), selectorState)
}

/**
 * 使用color创建 单一状态的selector
 */
fun createSelectorWithColor(normalColor: Int, otherStateColor: Int, selectorState: SelectorState): StateListDrawable {
    return createSelector(ColorDrawable(normalColor), ColorDrawable(otherStateColor), selectorState)
}

/**
 * 单一状态下创建selector
 * ```
 * 当传入[SelectorState.Pressed]状态时，等价于下面
 * <selector xmlns:android="http://schemas.android.com/apk/res/android">
 *     <item android:state_pressed="true" android:drawable="pressedDrawable" />
 *     <item android:state_pressed="false" android:drawable="normalDrawable"   />
 * </selector>
 * ```
 */
fun createSelector(normalDrawable: Drawable?, pressedDrawable: Drawable?, selectorState: SelectorState): StateListDrawable {
    val bg = StateListDrawable()
    val state = selectorState.state
    bg.addState(intArrayOf(-state), normalDrawable)
    bg.addState(intArrayOf(state), pressedDrawable)
    return bg
}

/**
 * press，enable 状态下的selector创建 一般用于button背景创建
 *
 * ```
 * 代码与下面selector等效
 *
 * <selector xmlns:android="http://schemas.android.com/apk/res/android">
 *     <item android:state_enabled="true"  android:state_pressed="true" android:drawable="pressedDrawable" />
 *     <item android:state_enabled="true"  android:state_pressed="false" android:drawable="normalDrawable"   />
 *     <item android:state_enabled="false" android:drawable="unEnabledDrawable"  />
 *     <item android:drawable="normalDrawable" />
 * </selector>
 *
 * ```
 */
fun createPressedAndEnabledSelector(
    normalDrawable: Drawable?,
    pressedDrawable: Drawable?,
    unEnabledDrawable: Drawable?
): StateListDrawable {
    val bg = StateListDrawable()
    bg.addState(intArrayOf(SelectorState.Pressed.state, SelectorState.Enabled.state), pressedDrawable)
    bg.addState(intArrayOf(-SelectorState.Pressed.state, SelectorState.Enabled.state), normalDrawable)
    bg.addState(intArrayOf(-SelectorState.Enabled.state), unEnabledDrawable)
    bg.addState(intArrayOf(), normalDrawable)
    return bg
}

/**
 *  文本颜色选择器
 */
fun createTextColorSelector(normalColor: Int, otherStateColor: Int, selectorState: SelectorState): ColorStateList {
    val state = selectorState.state
    val colors = intArrayOf(normalColor, otherStateColor)
    val states = arrayOfNulls<IntArray>(2)
    states[0] = intArrayOf(-state)
    states[1] = intArrayOf(state)
    return ColorStateList(states, colors)
}

/**
 *
 * 创建Shape,在这里演示几个使用
 *
 * ```
 * // 带圆角和填充色
 * test1.background = createShape(solidColor = R.color.live_red,
 *      cornerRadius = ShapeCornerRadius.Radius8
 * )
 *
 * // 不规则圆角和填充色 左上角8dp圆角,右上角16dp圆角
 * test2.background = createShape(
 *      solidColor = R.color.live_red.toResColor(),
 *      radii = arrayOf(
 *                  ShapeCornerRadius.Radius8,
 *                  ShapeCornerRadius.Radius8,
 *                  ShapeCornerRadius.Radius16,
 *                  ShapeCornerRadius.Radius16,
 *                  ShapeCornerRadius.RadiusNone,
 *                  ShapeCornerRadius.RadiusNone,
 *                  ShapeCornerRadius.RadiusNone,
 *                  ShapeCornerRadius.RadiusNone
 *      )
 * )
 *
 * // 演示一个渐变使用
 * test4.background = createShape(
 *     cornerRadius = ShapeCornerRadius.Radius8,
 *     gradientColors = intArrayOf(R.color.live_red.toResColor(), R.color.colorAccent.toResColor()),
 *     gradientOrientation = GradientDrawable.Orientation.RIGHT_LEFT
 * )
 * ```
 */
fun createShape(
    solidColor: Int? = null,
    cornerRadius: ShapeCornerRadius? = null,
    radii: Array<ShapeCornerRadius>? = null,
    strokeWidth: ShapeStokeWidth? = null,
    strokeColor: Int? = null,
    gradientColors: IntArray? = null,
    gradientOrientation: GradientDrawable.Orientation? = null,
    shape: Int = GradientDrawable.RECTANGLE,
): GradientDrawable {
    val drawable = GradientDrawable()
    drawable.shape = shape                      // shape 形状
    solidColor?.let {
        drawable.setColor(it)      // 设置填充色
    }

    if (shape == GradientDrawable.RECTANGLE) {
        // 设置4个圆角弧度
        cornerRadius?.let {
            drawable.cornerRadius = it.radius
        }
        // 4个圆角，不对等的情况设置如[16f,16f,0f,0f,0f,0f,16f,16f]
        radii?.let {
            val afterTransForRadii = it.map { item -> item.radius }.toFloatArray()
            drawable.cornerRadii = afterTransForRadii
        }
    }

    // 设置边框线条宽度和颜色
    strokeWidth?.let { width ->
        strokeColor?.let { color -> drawable.setStroke(width.width, color) }
    }

    // 设置渐变
    gradientOrientation?.let { orientation ->
        drawable.orientation = orientation
        gradientColors?.let {
            drawable.colors = it
        }

        // 渐变方式目前只支持线性渐变
        drawable.gradientType = GradientDrawable.LINEAR_GRADIENT
    }

    return drawable
}

fun createNormalButtonSelector(
    context: Context,
    normalColor: Int = R.color.cor_ff6839.toResColor(context),
    cornerRadius: ShapeCornerRadius = ShapeCornerRadius.Radius24,
    pressedColor: Int = R.color.cor_5d32.toResColor(context),
    unEnableColor: Int = R.color.cor_f1f1.toResColor(context),
    strokeColor: Int? = null,
    strokeWidth: ShapeStokeWidth? = null,
    unEnableStrokeColor: Int? = null,
    unEnableStrokeWidth: ShapeStokeWidth? = null
): StateListDrawable {
    val nc = normalColor.checkColor(R.color.cor_ff6839, context)
    val pc = pressedColor.checkColor(R.color.cor_5d32, context)
    val nec = unEnableColor.checkColor(R.color.cor_f1f1, context)

    val normalDrawable = createShape(
        solidColor = nc,
        cornerRadius = cornerRadius,
        strokeColor = strokeColor,
        strokeWidth = strokeWidth
    )
    val pressedDrawable = createShape(
        solidColor = pc,
        cornerRadius = cornerRadius,
        strokeColor = strokeColor,
        strokeWidth = strokeWidth
    )
    val unEnableDrawable = createShape(
        solidColor = nec,
        cornerRadius = cornerRadius,
        strokeColor = unEnableStrokeColor,
        strokeWidth = unEnableStrokeWidth
    )
    return createPressedAndEnabledSelector(normalDrawable, pressedDrawable, unEnableDrawable)
}

fun createGradientButtonSelector(
    context: Context,
    normalBegin: Int = R.color.c_931e.toResColor(context),
    normalEnd: Int = R.color.cor_ff6839.toResColor(context),
    pressBegin: Int = R.color.c_8a19.toResColor(context),
    pressEnd: Int = R.color.cor_5d32.toResColor(context),
    unEnableColor: Int = R.color.cor_f1f1.toResColor(context),
    unEnableEndColor: Int = 0,
    cornerRadius: ShapeCornerRadius = ShapeCornerRadius.Radius24,
    gradientOrientation: GradientDrawable.Orientation = GradientDrawable.Orientation.RIGHT_LEFT,
    unEnableStrokeColor: Int? = null,
    unEnableStrokeWidth: ShapeStokeWidth? = null
): StateListDrawable {

    val nb = normalBegin.checkColor(R.color.c_931e, context)
    val ne = normalEnd.checkColor(R.color.cor_ff6839, context)
    val pb = pressBegin.checkColor(R.color.c_8a19, context)
    val pe = pressEnd.checkColor(R.color.cor_5d32, context)
    val uec = unEnableColor.checkColor(R.color.cor_f1f1, context)

    val normalDrawable = createShape(
        cornerRadius = cornerRadius,
        gradientColors = intArrayOf(ne, nb),
        gradientOrientation = gradientOrientation
    )
    val pressedDrawable = createShape(
        cornerRadius = cornerRadius,
        gradientColors = intArrayOf(pe, pb),
        gradientOrientation = gradientOrientation
    )

    val unEnableDrawable: Drawable = if (unEnableEndColor == 0) {
        createShape(
            solidColor = uec,
            cornerRadius = cornerRadius,
            strokeColor = unEnableStrokeColor,
            strokeWidth = unEnableStrokeWidth
        )
    } else {
        createShape(
            cornerRadius = cornerRadius,
            strokeColor = unEnableStrokeColor,
            strokeWidth = unEnableStrokeWidth,
            gradientColors = intArrayOf(unEnableEndColor, uec),
            gradientOrientation = gradientOrientation
        )
    }

    return createPressedAndEnabledSelector(normalDrawable, pressedDrawable, unEnableDrawable)
}

private fun Int.checkColor(default: Int, context: Context) = if (this != 0) this else default.toResColor(context)

